package channels;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import org.apache.log4j.Logger;



public class TCPChannel implements Channel {

	private PrintWriter out = null;
	private BufferedReader in = null;
	private Socket client = null;
	private String hostname;
	private int tcpport;
	private static TCPChannel instance;
	private static final Object singletonObject = new Object();
	private static final Logger log = Logger.getLogger(TCPChannel.class);

	@Override
	public boolean open(String hostname, int tcpport) {
		this.hostname=hostname;
		this.tcpport=tcpport;
		return initSocket();
	}
	
	private TCPChannel() {
		
	}

	public TCPChannel(Socket client) {
		this.client = client;
		initSocket();
	}

	public static TCPChannel getInstance() {
		if(instance == null) {
			synchronized(singletonObject) {
				if(instance == null) instance = new TCPChannel();
			}
		}
		return instance;
	}

	@Override
	public void close() {
		out.close();

		try {
			in.close();
			client.close();
		} catch (IOException e1) {
			System.out.println("Error closing socket");
		}

	}

	@Override
	public void send(String message) {
		log.info("sending: "+message);
		out.println(message);
	}

	@Override
	public String read() {
		String response=null;
		try {
			response = in.readLine();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("Connection lost.");
		}
		log.info("reading: "+response);
		return response;
	}


	public boolean initSocket(){
		try {
			if(client == null) client = new Socket(hostname, tcpport);
			out = new PrintWriter(client.getOutputStream(), true);
			in = new BufferedReader(new InputStreamReader(client.getInputStream()));
			return true;

		} catch (UnknownHostException e) {
			//udpclient.close();
			System.out.println("Connection failed.");
			return false;
		} catch (IOException e) {
			//udpclient.close();
			System.out.println("Connection failed.");
			return false;
		}
		
	}

	public boolean isOpen() {
		if(client==null) return false;
		else return true;
	}

	@Override
	public String getAddress() {
		String address = client.getInetAddress().getHostAddress();
		return address;
	}

}
